﻿using System;
using System.Runtime.InteropServices;
using System.Security;

namespace AwesomiumDotNet
{
    /// <summary>
    /// The WebCore manages the creation of WebViews, the internal worker thread,
    /// and various other global states that are required to embed Chromium.
    /// </summary>
    public class WebCore : IDisposable
    {
        /// <summary>
        /// Instantiates the WebCore singleton (you can access it later with WebCore.Get.
        /// </summary>
        public WebCore() : this(new WebCoreConfig())
        {
        }

        /// <summary>
        /// Instantiates the WebCore singleton (you can access it later with WebCore.Get.
        /// </summary>
        /// <param name="config">
        /// Various configuration settings. See WebCoreConfig for more information.
        /// </param>
        public WebCore(WebCoreConfig config)
        {
            unsafe
            {
                unmanaged = (__WebCore*)Memory.Alloc(sizeof(__WebCore));
                WebCore_Ctor(unmanaged, config.unmanaged);
            }
        }

        /// <summary>
        /// Whether or not plugins are enabled.
        /// </summary>
        public bool ArePluginsEnabled
        {
            get
            {
                unsafe
                {
                    return WebCore_ArePluginsEnabled(unmanaged);
                }
            }
        }

        /// <summary>
        /// Destroys the WebCore singleton. (Also destroys any lingering WebViews)
        /// </summary>
        public void Dispose()
        {
            unsafe
            {
                //call destructor
                //WebCore_Dtor(_cpp);
                //release memory
                //Memory.Free(unmanaged);
                //unmanaged = null;
            }
        }

        /// <summary>
        /// Clear the disk cache and media cache.
        /// </summary>
        public unsafe void ClearCache()
        {
            WebCore_ClearCache(unmanaged);
        }

        /// <summary>
        /// Clear all cookies.
        /// </summary>
        public unsafe void ClearCookies()
        {
            WebCore_ClearCookies((__WebCore*)unmanaged);
        }

        /// <summary>
        /// Creates a new WebView.
        /// </summary>
        /// <param name="width">
        /// The width of the WebView in pixels.
        /// </param>
        /// <param name="height">
        /// The height of the WebView in pixels.
        /// </param>
        /// <returns>
        /// Returns a WebView Instance.
        /// </returns>
        public WebView CreateWebView(int width, int height)
        {
            unsafe
            {
                WebView.__WebViewClass* webView = 
                    WebCore_CreateWebView(unmanaged, width, height);
                return new WebView(webView);
            }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        unsafe struct __WebCore
        {
            void* webCoreImpl;
            wstring baseDirectory;
            int pluginsEnabled;
            astring customCSS;
            astring getCookiesCache;
        }

        unsafe __WebCore* unmanaged;

        [DllImport("Awesomium", EntryPoint = "??_FWebCore@Awesomium@@QAEXXZ", CallingConvention = CallingConvention.ThisCall), SuppressUnmanagedCodeSecurityAttribute]
        unsafe extern static void WebCore_Ctor(__WebCore* inst); // Default constructor, don't use

        [DllImport("Awesomium", EntryPoint = "??0WebCore@Awesomium@@QAE@ABV01@@Z", CallingConvention = CallingConvention.ThisCall), SuppressUnmanagedCodeSecurityAttribute]
        unsafe extern static void WebCore_Ctor(__WebCore* inst, WebCoreConfig.__WebCoreConfig* config);

        [DllImport("Awesomium", EntryPoint = "??1WebCore@Awesomium@@QAE@XZ", CallingConvention = CallingConvention.ThisCall), SuppressUnmanagedCodeSecurityAttribute]
        unsafe extern static void WebCore_Dtor(__WebCore* inst);

        [DllImport("Awesomium", EntryPoint = "?arePluginsEnabled@WebCore@Awesomium@@QBE_NXZ", CallingConvention = CallingConvention.ThisCall), SuppressUnmanagedCodeSecurityAttribute]
        unsafe extern static bool WebCore_ArePluginsEnabled(__WebCore* inst);

        [DllImport("Awesomium", EntryPoint = "?createWebView@WebCore@Awesomium@@QAEPAVWebView@2@HH@Z", CallingConvention = CallingConvention.ThisCall), SuppressUnmanagedCodeSecurityAttribute]
        unsafe extern static WebView.__WebViewClass* WebCore_CreateWebView(__WebCore* inst, int width, int height);

        [DllImport("Awesomium", EntryPoint = "?clearCache@WebCore@Awesomium@@QAEXXZ", CallingConvention = CallingConvention.ThisCall), SuppressUnmanagedCodeSecurityAttribute]
        unsafe extern static void WebCore_ClearCache(__WebCore* inst);

        [DllImport("Awesomium", EntryPoint = "?clearCookies@WebCore@Awesomium@@QAEXXZ", CallingConvention = CallingConvention.ThisCall), SuppressUnmanagedCodeSecurityAttribute]
        unsafe extern static void WebCore_ClearCookies(__WebCore* inst);

        [DllImport("Awesomium", EntryPoint = "?Get@WebCore@Awesomium@@SAAAV12@XZ", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurityAttribute]
        unsafe extern static __WebCore* WebCore_Get();

        [DllImport("Awesomium", EntryPoint = "?GetPointer@WebCore@Awesomium@@SAPAV12@XZ", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurityAttribute]
        unsafe extern static __WebCore* WebCore_GetPointer();

        [DllImport("Awesomium", EntryPoint = "?setCustomResponsePage@WebCore@Awesomium@@QAEXHABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z", CallingConvention = CallingConvention.ThisCall), SuppressUnmanagedCodeSecurityAttribute]
        unsafe extern static void WebCore_SetCustomResponsePage(__WebCore* inst, int statusCode, astring* filePath);
    }
}
